<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>MixIO管理后台</title>
    <link rel="shortcut icon" href="img/shortcut.png"/>
    <link rel="stylesheet" href="css/all.css">
    <script src="js/jquery.min.js"></script>
    
    <script src="js/lang.js?v=5"></script>
    <script src="js/farbtastic.js"></script>
    <script src="js/bootstrap.bundle.min.js"></script>
    <script src="js/jquery.easing.min.js"></script>
    <script src="js/echarts.min.js"></script>
    <script src="js/mqtt.min.js"></script>
    <link rel="stylesheet" href="css/dataTables.bootstrap4.min.css">
    <script src="js/jquery.dataTables.min.js"></script>
    <script src="js/dataTables.bootstrap4.min.js"></script>
    <script src="js/tools.js?v=14"></script>
    <script src="js/manage.js"></script>
</head>

<body id="page-top" class="sidebar-toggled" style="position:relative;overflow-x:hidden;color: black;">
    <div id="wrapper">
        <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
            <a class="sidebar-brand d-flex align-items-center justify-content-center" href="index">
                <div class="sidebar-brand-icon">
                    <i class="fa fa-cog"></i>
                </div>
                <div class="sidebar-brand-text mx-3" >MixIO Admin</div>
            </a>
            <hr class="sidebar-divider my-0">
            <hr class="sidebar-divider">
            <div class="sidebar-heading lang" key="MANAGE">
            </div>
            <li class="nav-item active" id="view1">
                <a class="nav-link" href="/admin?page=basic" style="cursor: pointer;" id="manage_prj">
                    <i class="fa fa-fw fa-tachometer"></i>
                    <span class="lang" key="BASICADMIN"></span></a>
            </li>
            <li class="nav-item" id="view2">
                <a class="nav-link" href="/admin?page=user" style="cursor: pointer;" id="manage_data">
                    <i class="fa fa-fw fa-database"></i>
                    <span class="lang" key="DATAADMIN"></span></a>
            </li>
            <li class="nav-item" id="view3">
                <a class="nav-link" href="/admin?page=batch" style="cursor: pointer;" id="manage_strg">
                    <i class="fa fa-fw fa-user"></i>
                    <span class="lang" key="USERADMIN"></span></a>
            </li>

            <hr class="sidebar-divider">
        </ul>
        <div id="content-wrapper" class="d-flex flex-column">
            <div id="content">
                <nav class="navbar navbar-expand navbar-light bg-white topbar static-top shadow" style="display:flex;justify-content:space-between" id="project_nav">
                    <h1 class="d-sm-inline-block h3 mb-0 text-gray-800 lang" key="ADMIN" id="title" style="margin-left:10px;font-size:1.25rem;display:inline-block;"></h1>
                </nav>
                <div class="container-fluid" id="detail">
                    <div id="detail1" class="row">
                        <div class="col-xl-4 col-md-6 mb-4">
                            <div class="card shadow" style="margin-top:1.5rem;border-radius:10px">
                                <div class="card-body">
                                    <div class="card border-left-primary h-100 py-2" style="margin-bottom:15px">
                                        <div class="card-body">
                                            <div class="row no-gutters align-items-center">
                                                <div class="col mr-2">
                                                    <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
                                                        平台类型</div>
                                                    <div class="h5 mb-0 font-weight-bold text-gray-800" id="platform"><%=platform%></div>
                                                </div>
                                                <div class="col-auto">
                                                    <i class="fa fa-code fa-2x text-gray-300"></i>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="card border-left-primary h-100 py-2" style="margin-bottom:15px">
                                        <div class="card-body">
                                            <div class="row no-gutters align-items-center">
                                                <div class="col mr-2">
                                                    <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
                                                        MixIO版本号</div>
                                                    <div class="h5 mb-0 font-weight-bold text-gray-800"><%=version%></div>
                                                </div>
                                                <div class="col-auto">
                                                    <i class="fa fa-code fa-2x text-gray-300"></i>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="card border-left-primary h-100 py-2" style="margin-bottom:15px">
                                        <div class="card-body">
                                            <div class="row no-gutters align-items-center">
                                                <div class="col mr-2">
                                                    <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
                                                        Mixly编程服务器版本号</div>
                                                    <div class="h5 mb-0 font-weight-bold text-gray-800"><%=versionmixly%></div>
                                                </div>
                                                <div class="col-auto">
                                                    <i class="fa fa-code fa-2x text-gray-300"></i>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="card border-left-primary h-100 py-2">
                                        <div class="card-body">
                                            <div class="row no-gutters align-items-center">
                                                <div class="col mr-2">
                                                    <div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
                                                        服务器时钟</div>
                                                    <div class="h5 mb-0 font-weight-bold text-gray-800" id="time"></div>
                                                </div>
                                                <div class="col-auto">
                                                    <i class="fa fa-hourglass-half fa-2x text-gray-300"></i>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="row" style="display:flex;align-items:center;justify-content:center">
                                        <button class="btn btn-lg btn-primary" style="margin-top:20px;margin-right:10px"  onclick="fresh('mixio', '<%=platform%>')"><i class="fa fa-refresh"></i> 更新MixIO服务器</button>            
                                    </div>
                                    <div class="row" style="display:flex;align-items:center;justify-content:center">
                                        <button class="btn btn-lg btn-primary" style="margin-top:20px;margin-right:10px"  onclick="fresh('mixly', 'all')"><i class="fa fa-refresh"></i> 更新Mixly编程服务器</button>           
                                        <!--                   
                                        <% if (status=="运行中") { %>
                                            <button class="btn btn-lg btn-danger" style="margin-top:20px;margin-left:10px"  onclick="stopServer()"><i class="fa fa-ban"></i> 暂停服务器</button>
                                        <%} else { %>
                                            <button class="btn btn-lg btn-success" style="margin-top:20px;margin-left:10px"  onclick="startServer()"><i class="fa fa-play"></i> 启动服务器</button>
                                        <% } %> 
                                        -->  
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="col-xl-8 col-md-6 mb-4">
                        
                            <div class="card shadow" style="margin-top:1.5rem;border-radius:10px">
                                <div class="card-body" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
                                    <table id="configTable">
                                        <thead>
                                            <tr>
                                                <th scope="col" width="30%">配置项</th>
                                                <th scope="col" width="30%">含义</th>
                                                <th scope="col" width="10%">数据类型</th>
                                                <th scope="col" width="30%">值</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            
                                        </tbody>
                                    </table>
                                    <button class="btn btn-lg btn-success" style="margin-top:20px;"  onclick="saveAndRestart()" id="saveAndRestart"><i class="fa fa-check"></i> 保存设置并重新启动</button>
                                </div>
                            </div>
                            
                        </div>
                    </div>
                    <div id="detail3" hidden>
                        <div class="col-xl-8 col-md-6 mb-4">
                            <div class="card shadow" style="margin-top:1.5rem;border-radius:10px">
                                <div class="card-body" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
                                    <p>格式（每个账号一行）: 账号,密码,密保问题,问题答案</p>
                                    <textarea name="" id="acc" rows="10" style="margin-bottom: 20px;width:95%">12345@mixly.com,123456,你就读的班级是？,三年二班</textarea>
                                    <div>
                                        <button class="btn btn-lg btn-success" onclick="addAcc()"><i class="fa fa-check"></i> 确定添加</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div id="detail2" hidden>
                        <div class="col-xl-12 col-md-6 mb-4">
                            <div class="card shadow" style="margin-top:1.5rem;border-radius:10px">
                                <div class="card-body" >
                                    <table id="table">
                                        <thead>
                                            <td style="min-width:100px">
                                                用户
                                            </td>
                                            <td style="min-width:100px">
                                                项目数
                                            </td>
                                            <td style="min-width:100px">
                                                消息量
                                            </td>
                                            <td style="min-width:300px">
                                                执行操作
                                            </td>
                                        </thead>
                                        <tbody id="tbody">

                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div> 
                </div>
            </div>
        </div>
    <style>
        input{
            min-width:0!important;
            height:30px
        }
        td{
            min-height: 30px;
        }
        table {
            border-collapse: separate;
            border-spacing: 0;
            width: 100%;
        }
        th {
            background-color: #2c3e50;
            color: white;
            font-weight: 500;
        }
        th:first-child {
            border-top-left-radius: 8px;
        }
        th:last-child {
            border-top-right-radius: 8px;
        }
        tr:nth-child(even) {
            background-color: #f8f9fa;
        }
        tr:hover {
            background-color: #e8f4fc;
        }
        td, th {
            padding: 0.5rem !important;
            vertical-align: middle !important;
        }
        .action-buttons {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            margin-top: 25px;
        }
        .badge-type {
            font-size: 0.8em;
            padding: 4px 8px;
            border-radius: 4px;
        }
        .badge-string {
            background-color: #3498db;
        }
        .badge-number {
            background-color: #2ecc71;
        }
        .badge-boolean {
            background-color: #e74c3c;
        }
        .form-control:focus, .form-select:focus {
            box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.3);
            border-color: #3498db;
        }
        .table-responsive {
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
        }
    </style>
    <script>
        var clearMessage = function(userName){
            $.get('clearMessage',{
                "userName":userName
            },function(res){
                if(res == 1)
                {
                    showtext("操作成功！")
                    setTimeout(function(){
                        window.location.href = window.location.href.split("?")[0] + "?page=user"
                    },1000)
                }
                else
                {
                    showtext("操作失败")
                }
            })
        }
        var resetPassword = function(userName){
            if (!confirm(`确定要重置用户 ${userName} 的密码吗？新密码将设置为 "123456"`)) {
                return;
            }
            const modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>重置密码中...</p></div>");
            $.get('resetf',{
                "username":userName,
                "password":"123456"
            },function(res){
                if(res == 1)
                {
                    modald.close()
                    showtext("操作成功！")
                    setTimeout(function(){
                        window.location.href = window.location.href.split("?")[0] + "?page=user"
                    },1000)
                }
                else
                {
                    modald.close()
                    showtext("操作失败")
                }
            })
        }
        var removeUser = function(userName){
            if (!confirm(`确定要删除用户 ${userName} 的账号吗？此操作将不可恢复！`)) {
                return;
            }
            const modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>重置密码中...</p></div>");
            $.get('deletef',{
                "username":userName
            },function(res){
                if(res == 1)
                {
                    modald.close()
                    showtext("操作成功！")
                    setTimeout(function(){
                        window.location.href = window.location.href.split("?")[0] + "?page=user"
                    },1000)
                }
                else
                {
                    modald.close()
                    showtext("操作失败")
                }
            })
        }
        $("#time").html(new Date().toLocaleTimeString())
        setInterval(() => {
            $("#time").html(new Date().toLocaleTimeString())
        }, 1000);
        var configs = <%-configs%>
        $("#OFFLINE_MODE").bind('change',function(){
            if($("#OFFLINE_MODE").prop("checked"))
            {
                $("#BAIDU_MAP_AK").attr("disabled","true")
                $("#BAIDU_MAP_SERVER_AK").attr("disabled","true")
            }
            else
            {
                $("#BAIDU_MAP_AK").removeAttr("disabled")
                $("#BAIDU_MAP_SERVER_AK").removeAttr("disabled")
            }
        })
        var loadConfig = function(){
            var mapping = {
                "MIXIO_HTTP_PORT": "HTTP端口",
                "MIXIO_HTTPS_PORT": "HTTPS端口",
                "HTTPS_PRIVATE_PEM": "私钥链接(本地或在线地址)",
                "HTTPS_CRT_FILE": "证书链接(本地或在线地址)",
                "MIXIO_MQTT_PORT": "MQTT端口",
                "MIXIO_WS_PORT": "MQTT-ws端口",
                "MIXIO_WSS_PORT": "MQTT-wss端口",
                "MAX_PROJECT_NUM_PER_USER": "用户的最大项目数",
                "MAX_MESSAGE_PER_USER": "用户的最大离线消息存储数",
                "MAX_MESSAGE_PER_SECOND": "用户每秒的最大消息数",
                "ALLOW_REGISTER": "是否允许自主注册",
                "ALLOW_HOOK": "是否允许离线存储消息",
                "OFFLINE_MODE": "是否禁用天气/地图数据",
                "BAIDU_MAP_AK": "百度地图客户端应用AK",
                "BAIDU_MAP_SERVER_AK": "百度地图服务端应用AK",
                "TENCENT_MAP_KEY": "腾讯地图key",
                "BAIDU_STAT_LINK": "百度统计链接",
                "ADMIN_USERNAME": "管理后台用户名",
                "ADMIN_PASSWORD": "管理后台密码",
                "STORAGE_ENGINE": "数据库引擎",
                "MYSQL_HOST": "mysql地址",
                "MYSQL_PORT": "mysql端口",
                "MYSQL_USER": "mysql用户名",
                "MYSQL_PASS": "mysql密码",
                "MYSQL_DB": "mysql数据库名",
                "FOOTER": "显示在首页的备案信息"
            }
            const tbody = document.querySelector('#configTable tbody');
            tbody.innerHTML = '';
            
            for (const [key, value] of Object.entries(configs)) {
                const tr = document.createElement('tr');
                
                // 配置名
                const tdKey = document.createElement('td');
                tdKey.textContent = key;
                const tdName = document.createElement('td');
                tdName.textContent = mapping[key];
                
                // 数据类型
                const tdType = document.createElement('td');
                const type = typeof value;
                const badge = document.createElement('span');
                badge.className = `badge badge-type badge-${type}`;
                badge.textContent = type;
                tdType.appendChild(badge);
                
                // 配置值
                const tdValue = document.createElement('td');
                let inputElement;
                
                if (type === 'boolean') {
                    inputElement = document.createElement('select');
                    inputElement.className = 'form-control';
                    inputElement.innerHTML = `
                        <option value="true" ${value ? 'selected' : ''}>是 (true)</option>
                        <option value="false" ${!value ? 'selected' : ''}>否 (false)</option>
                    `;
                } else if (type === 'number') {
                    inputElement = document.createElement('input');
                    inputElement.type = 'number';
                    inputElement.className = 'form-control';
                    inputElement.value = value;
                    inputElement.step = Number.isInteger(value) ? '1' : '0.01';
                } else {
                    console.log(key)
                    inputElement = document.createElement('input');
                    inputElement.type = (mapping[key].indexOf('密码')==-1?'text':'password');
                    inputElement.className = 'form-control';
                    inputElement.value = value;
                }
                inputElement.setAttribute('data-key', key);
                tdValue.appendChild(inputElement);
                tr.appendChild(tdKey);
                tr.appendChild(tdName);
                tr.appendChild(tdType);
                tr.appendChild(tdValue);
                
                tbody.appendChild(tr);
            }

        }
        loadConfig()
        
        
        var saveAndRestart = function(){
            var modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>"+JSLang[lang].loading2+"</p></div>")
            const inputs = document.querySelectorAll('#configTable input, #configTable select');
            configs = {};
            
            inputs.forEach(input => {
                const key = input.getAttribute('data-key');
                const originalType = input.getAttribute('type');
                
                if (originalType === 'text' || originalType === 'password') {
                    configs[key] = input.value;
                } else if (originalType === 'number') {
                    configs[key] = Number(input.value);
                } else {
                    configs[key] = input.value === 'true'
                }
            });
            console.log(configs)
            $.get('/saveAndRestart',{'configs':JSON.stringify(configs,null,2)},function(res){
                if(res=="1")
                {
                    showtext('保存成功, 正在重新启动服务器。')
                }
                else
                    showtext('保存失败')
                modald.close()
            })
        }
        var stopServer = function(){
            var modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>"+JSLang[lang].loading2+"</p></div>")
            $.get('/stop',function(res){
                modald.close()
                if(res=="1")
                {
                    window.location.href = window.location.href
                }
                else
                    showtext('状态异常')
            })
        }
        var startServer = function(){
            var modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>"+JSLang[lang].loading2+"</p></div>")
            $.get('/start',function(res){
                modald.close()
                if(res=="1")
                {
                    window.location.href = window.location.href
                }
            })
        }
        
        var fresh = function(product, platform){
            var textarea = $("<textarea readonly cols='50' rows='20' style='color:white; background-color:black'></textarea>")
            var add_text = function(text){
                textarea.text(textarea.text() + text + "\n")
                textarea.scrollTop(textarea[0].scrollHeight);
            }
            var d = dialog({
                content: textarea
            });
            d.showModal();
            add_text("发送更新请求中...")
            fetch('/api/check-update', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    product: product,
                    platform: platform
                })
            })
            .then((response) => response.json())
            .then((result) => {
                add_text("本地版本：" + result["localVersion"])
                add_text("云端版本：" + result["cloudVersion"])
                add_text("需要更新：" + result["needsUpdate"])
                var url = result["cloudFile"]
                var error = result["error"]
                if(error)
                {
                    add_text(error)
                }
                if(result["needsUpdate"])
                {
                    const eventSource = new EventSource(`/api/download?url=${encodeURIComponent(url)}&cloudVersion=${result["cloudVersion"]}`);
                    add_text("下载开始...")
                    eventSource.onmessage = function(event) {
                        console.log(event)
                        const data = JSON.parse(event.data);
                        console.log(data)
                        if (data.type === 'progress') {
                            add_text(`下载中: ${data.progress}%`)
                        } 
                        else if (data.type === 'unzip') {
                            add_text(`解压中...`)
                        } 
                        else if (data.type === 'complete') {
                            add_text(`${data.version}更新完成！`);
                            eventSource.close();
                            if(data.version == "mixio"){
                                setTimeout(
                                    function(){
                                        window.location.reload()
                                    }
                                , 10000)
                                alert("更新已完成，请务必手动重启MIXIO服务，请务必手动重启MIXIO服务，如果是支持自动启动，那么请直接重启服务器机器即可！！！")
                            }
                            else{
                                alert("更新已完成！")
                            }
                            add_text('5秒后自动退出...');
                            setTimeout(function(){
                                d.close()
                            }, 5000)
                            window.location.reload()
                        }
                    };
                    eventSource.onerror = function(error) {
                        console.log(error)
                        add_text('下载失败！5秒后自动退出...');
                            setTimeout(function(){
                            d.close()
                        }, 5000)
                        eventSource.close();
                    };
                }
                else
                {
                    add_text("已经是最新版本！5秒后自动退出...")
                    setTimeout(function(){
                        d.close()
                    }, 5000)
                }
            })
            .catch((error) => {
                add_text(error);
            });
        }
        var view = function(index){
            a = [1,2,3]
            for (i in a){
                v = a[i]
                if (index==v){
                    $("#detail"+v).removeAttr("hidden")
                    $("#view"+v).addClass("active")
                }
                else
                {
                    $("#detail"+v).attr("hidden","hidden")
                    $("#view"+v).removeClass("active")
                }
            }
        }
        // 尝试获取page参数
        if(window.location.href.split("?").length > 1){
            var page = window.location.href.split("?")[1].split("=")[1]
            if (page == "user")
                view(2)
            else if(page == "basic")
                view(1)
            else if(page == "batch")
                view(3)
        }
        var addAcc = function(){
            var modald = showmodaltext("<div style='text-align:center'><i class='fa fa-spin fa-cog' style='font-size:2rem;color:#4e73df'></i><p style='margin-top:6px;margin-bottom:0;color:#4e73df;font-size:1rem;font-weight:bold'>"+JSLang[lang].loading2+"</p></div>")
            var acc = $("#acc").val()
            accs = acc.split('\n')
            acct = []
            for(acc in accs){
                if(accs[acc]!="")
                    acct.push(accs[acc])
            }
            var successCount = 0
            var failCount = 0
            var failInfo = []
            for(i in acct){
                info = acct[i].split(',')
                if(info.length!=4)
                {
                    failCount+=1
                    failInfo.push({
                        'account':info[0],
                        'reason':'格式不正确'
                    })
                }
                else
                {
                    $.get('addAccount',{'userName':info[0],'password':info[1],'question':info[2],'answer':info[3]},function(res){
                        modald.close()
                        if(res=='1')
                            successCount+=1
                        else if(res=='2')
                        {
                            failCount+=1
                            failInfo.push({
                                'account':info[0],
                                'reason':'用户已存在'
                            })
                        }
                        else if(res=='3')
                        {
                            failCount+=1
                            failInfo.push({
                                'account':info[0],
                                'reason':'连接失败'
                            })
                        }
                        var s = "成功个数："+successCount+"; 失败个数："+failCount+"; 失败原因："+JSON.stringify(failInfo)
                        showtext(s)
                    })
                }
            }
        }
    </script>
</body>